package window;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import main.DataConnection;
import main.OutcomeProblem;

import org.jdesktop.layout.GroupLayout;
import org.jdesktop.layout.LayoutStyle;

/**
 * Window for changing its characteristics.
 * 
 * @author Dawid Nejman
 * @version 1.3 17-12-2011
 */
public class ItsCharacteristicsWindow extends JFrame {

	private static final long serialVersionUID = -3430165872594322306L;
	private JComboBox<String> firstComboBox;
	private JLabel itsLabel;
	private JButton jButton1;
	private JTextField percentageTextField;
	private JComboBox<String> secondComboBox;
	private JLabel problemLabel;
	private JLabel reductionLabel;
	private JLabel influenceLabel;
	private String[] firstNames;
	private String[] secondNames;
	public final static int ITS_CHARACTERISTICS = 0;
	public final static int ADD_PROBLEM = 1;
	private final int mode;
	private final AddItsWindow delegate;
	private JTextField inflTxtField;
	private JSlider sldrInfluence;

	/**
	 * Creates new form NewJFrame
	 * 
	 * @param mode
	 *            creates either {@code ITS_CHARACTERISTICS} or {@code ADD_PROBLEM} window.
	 */
	public ItsCharacteristicsWindow() {
		this.firstNames = DataConnection.getItsNames();
		this.secondNames = DataConnection.getProblemNames();
		this.mode = ITS_CHARACTERISTICS;
		this.delegate = null;

		initComponents();
	}

	public ItsCharacteristicsWindow(AddItsWindow delegate) {
		this.firstNames = DataConnection.getProblemNames();
		this.secondNames = DataConnection.getSubproblemNamesForProblem(this.firstNames[0]);
		this.mode = ADD_PROBLEM;
		this.delegate = delegate;

		initComponents();
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 */
	private void initComponents() {
		firstComboBox = new JComboBox<String>();
		secondComboBox = new JComboBox<String>();
		percentageTextField = new JTextField();
		itsLabel = new JLabel();
		problemLabel = new JLabel();
		reductionLabel = new JLabel();
		influenceLabel = new JLabel("Influenced cars");
		jButton1 = new JButton();
		sldrInfluence = createSliderInfl();
		inflTxtField = new JTextField("100%");
		
		addSliderIfnlListener();
		addTxtFieldListener();

		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

		firstComboBox.setModel(new DefaultComboBoxModel<String>(firstNames));
		firstComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if (mode == ITS_CHARACTERISTICS) {
					double percent = getPercentOfReduction();
					percentageTextField.setText("" + (int) (percent * 100 + 0.5) + "%");
				} else {
					updateComboBox();
				}
			}
		});

		secondComboBox.setModel(new DefaultComboBoxModel<String>(secondNames));
		if (mode == ITS_CHARACTERISTICS)
			secondComboBox.setToolTipText("Problem");
		else
			secondComboBox.setToolTipText("Subproblem");
		secondComboBox.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if (mode == ITS_CHARACTERISTICS) {
					double percent = getPercentOfReduction();
					percentageTextField.setText("" + (int) (percent * 100 + 0.5) + "%");
				}
			}
		});

		itsLabel.setHorizontalAlignment(SwingConstants.CENTER);
		if (mode == ITS_CHARACTERISTICS) {
			this.setTitle("Modify ITS");
			firstComboBox.setToolTipText("ITS");
			itsLabel.setText("ITS");
			problemLabel.setText("Problem");
			jButton1.setText("Change");
			reductionLabel.setText("Reduction");
			double percent = getPercentOfReduction();
			percentageTextField.setText("" + (int) (percent * 100 + 0.5) + "%");
			inflTxtField.setEditable(false);
		} else {
			this.setTitle("Add Problem");
			firstComboBox.setToolTipText("Problem");
			itsLabel.setText("Problem");
			problemLabel.setText("Subproblem");
			jButton1.setText("Add");
			reductionLabel.setText("Size");
			inflTxtField.setEditable(false);
		}

		problemLabel.setHorizontalAlignment(SwingConstants.CENTER);
		jButton1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				if (mode == ITS_CHARACTERISTICS)
					setPercentOfReduction();
				else
					returnItsProblemValue();
			}
		});

		GroupLayout layout = new GroupLayout(getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.LEADING).add(
				layout.createSequentialGroup()
						.addContainerGap()
						.add(layout
								.createParallelGroup(GroupLayout.LEADING)
								.add(layout
										.createSequentialGroup()
										.add(layout.createParallelGroup(GroupLayout.LEADING, false)
												.add(firstComboBox, GroupLayout.PREFERRED_SIZE, 138, GroupLayout.PREFERRED_SIZE)
												.add(itsLabel, GroupLayout.PREFERRED_SIZE, 138, GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(LayoutStyle.RELATED)
										.add(layout.createParallelGroup(GroupLayout.LEADING, false)
												.add(secondComboBox, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
												.add(problemLabel, GroupLayout.PREFERRED_SIZE, 118, GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(LayoutStyle.RELATED)
										.add(layout.createParallelGroup(GroupLayout.LEADING).add(reductionLabel)
												.add(percentageTextField, GroupLayout.PREFERRED_SIZE, 74, GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(LayoutStyle.RELATED)
										.add(layout.createParallelGroup(GroupLayout.LEADING).add(influenceLabel)
												.add(inflTxtField, GroupLayout.PREFERRED_SIZE, 54, GroupLayout.PREFERRED_SIZE)
												.add(sldrInfluence, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE))
										.add(0, 6, Short.MAX_VALUE))
								.add(GroupLayout.TRAILING, layout.createSequentialGroup().add(0, 0, Short.MAX_VALUE).add(jButton1))).addContainerGap()));
		layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.LEADING).add(
				layout.createSequentialGroup()
						.addContainerGap()
						.add(layout.createParallelGroup(GroupLayout.BASELINE).add(itsLabel).add(problemLabel).add(reductionLabel).add(influenceLabel))
						.addPreferredGap(LayoutStyle.RELATED)
						.add(layout.createParallelGroup(GroupLayout.BASELINE)
								.add(firstComboBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.add(secondComboBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.add(percentageTextField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.add(inflTxtField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
								.add(sldrInfluence, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
						.addPreferredGap(LayoutStyle.RELATED).add(jButton1).addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));

		pack();
	}

	private void setPercentOfReduction() {
		int index = secondComboBox.getSelectedIndex();
		String problem = secondComboBox.getItemAt(index);
		index = firstComboBox.getSelectedIndex();
		String its = firstComboBox.getItemAt(index);
		String text = percentageTextField.getText();
		
		if (text.endsWith("%")) {
			int place = text.indexOf("%");
			text = text.substring(0, place);
		}
		double percent = Double.valueOf(text) / 100.0;
		
		DataConnection.setPercentOfReduction(its, problem, "Total", percent);
		
		super.dispose();
	}

	private double getPercentOfReduction() {
		double percent = 0.0;
		int index = secondComboBox.getSelectedIndex();
		String problem = secondComboBox.getItemAt(index);
		index = firstComboBox.getSelectedIndex();
		String its = firstComboBox.getItemAt(index);
		percent = DataConnection.getPercentOfReduction(its, problem, "Total");

		return percent;
	}

	private void updateComboBox() {
		int index = firstComboBox.getSelectedIndex();
		String problem = firstComboBox.getItemAt(index);
		DefaultComboBoxModel<String> dcbm = (DefaultComboBoxModel<String>) secondComboBox.getModel();
		int size = dcbm.getSize();
		for (int i = size - 1; i > 0; i--) {
			dcbm.removeElementAt(i);
		}
		this.secondNames = DataConnection.getSubproblemNamesForProblem(problem);
		for (String str : secondNames)
			dcbm.addElement(str);
		dcbm.removeElementAt(0);
	}

	public void returnItsProblemValue() {
		OutcomeProblem op = this.delegate.getOp();
		int index = firstComboBox.getSelectedIndex();
		String problem = firstComboBox.getItemAt(index);
		index = this.secondComboBox.getSelectedIndex();
		String subproblem = this.secondComboBox.getItemAt(index);
		String value = this.percentageTextField.getText();

		op.setProblem(problem);
		op.setSubproblem(subproblem);
		op.setSize(value);
		this.delegate.refreshTable();

		dispose();
	}
	
	private void addSliderIfnlListener() {
		sldrInfluence.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent arg0) {
				if (!sldrInfluence.getValueIsAdjusting()) {
					inflTxtField.setText(String.valueOf(sldrInfluence.getValue())+"%");
				}
			}
			
		});
		
		sldrInfluence.addMouseListener(new MouseListener() {
			
			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mouseExited(MouseEvent e) {					
				sldrInfluence.setVisible(false);
			}
			
			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub
				
			}
		});
	}
	
	private void addTxtFieldListener() {
		inflTxtField.addMouseListener(new MouseListener() {		

			@Override
			public void mouseClicked(MouseEvent arg0) {
				if(sldrInfluence.isVisible())
					sldrInfluence.setVisible(false);
				else
					sldrInfluence.setVisible(true);
				
			}

			@Override
			public void mouseEntered(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseExited(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mousePressed(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseReleased(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
		});
		
	}
	
	private JSlider createSliderInfl() {
		JSlider slider = new JSlider();
		slider.setValue(100);
		slider.setMajorTickSpacing(10);
		slider.setMinorTickSpacing(1);
		slider.setOrientation(SwingConstants.VERTICAL);
		slider.setVisible(false);
		
		return slider;
	}
	
	public int getInfluenceValue(){
		String inflTxt = inflTxtField.getText();
		inflTxt = inflTxt.substring(0, inflTxt.length()-1);
		return Integer.parseInt(inflTxt);
	}
}
